package com.ruoyi.system.service.impl;

import com.aliyun.com.viapi.FileUtils;
import com.aliyun.ocr20191230.models.RecognizeLicensePlateResponse;
import com.aliyun.ocr20191230.models.RecognizeLicensePlateResponseBody;
import com.aliyun.tea.TeaModel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.bean.BeanUtils;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.domain.Parking;
import com.ruoyi.system.domain.ParkingPayment;
import com.ruoyi.system.domain.Vehicle;
import com.ruoyi.system.domain.dto.VehicleDto;
import com.ruoyi.system.domain.vo.VehicleVo;
import com.ruoyi.system.mapper.VehicleMapper;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.system.service.ParkingService;
import com.ruoyi.system.service.VehicleService;
import com.zhentao.service.impl.FileStorageServiceImpl;
import lombok.SneakyThrows;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author 22115
 * @description 针对表【vehicle】的数据库操作Service实现
 * @createDate 2025-02-11 19:06:43
 */
@Service
public class VehicleServiceImpl extends ServiceImpl<VehicleMapper, Vehicle>
        implements VehicleService {

    @Resource
    FileStorageServiceImpl fileStorageService;
    @Resource
    ParkingService parkingService;
    @Resource
    ParkingPaymentServiceImpl parkingPaymentService;

    /**
     * 通过id获取到用户
     * 吴轩琦
     */
    @Resource
    ISysUserService iSysUserService;

//    @Resource
//    SnowflakeIdGenerator snowflakeIdGenerator;

    public static com.aliyun.ocr20191230.Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
       /*
          初始化配置对象com.aliyun.teaopenapi.models.Config
          Config对象存放 AccessKeyId、AccessKeySecret、endpoint等配置
         */
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
                .setAccessKeyId(accessKeyId)
                .setAccessKeySecret(accessKeySecret);
        // 访问的域名
        config.endpoint = "ocr.cn-shanghai.aliyuncs.com";
        return new com.aliyun.ocr20191230.Client(config);
    }

    @Override
    public AjaxResult VehicList(VehicleDto vehicleDto) {
        Page<Vehicle> vehiclePage = new Page<>(vehicleDto.getPageNum(), vehicleDto.getPageSize());

        Page<VehicleVo> vehicleVoPage = new Page<>(vehicleDto.getPageNum(), vehicleDto.getPageSize());

        LambdaQueryWrapper<Vehicle> vehicleLambdaQueryWrapper = new LambdaQueryWrapper<>();
        vehicleLambdaQueryWrapper.eq(StringUtils.isNotNull(vehicleDto.getStatus()), Vehicle::getStatus, vehicleDto.getStatus());
        vehicleLambdaQueryWrapper.like(StringUtils.isNotNull(vehicleDto.getCarNumber()), Vehicle::getCarNumber, vehicleDto.getCarNumber());

        Page<Vehicle> page = this.page(vehiclePage, vehicleLambdaQueryWrapper);

        List<VehicleVo> vehicleVos = new ArrayList<>();
        List<Vehicle> records = page.getRecords();
        for (int i = 0; i < records.size(); i++) {
            VehicleVo vehicleVo = new VehicleVo();
            BeanUtils.copyBeanProp(vehicleVo, records.get(i));
            //获取用户名
            SysUser sysUser = iSysUserService.selectUserById(records.get(i).getUserId().longValue());
            if (records.get(i).getStatus() != 0) {
                vehicleVo.setUserName(sysUser.getUserName());
            } else {
                vehicleVo.setUserName("未知");
            }

            vehicleVos.add(vehicleVo);
        }

        vehicleVoPage.setRecords(vehicleVos);
        return AjaxResult.success(vehicleVoPage);
    }

    @Override
    @Transactional
    @SneakyThrows
    public AjaxResult recognition(@RequestParam("file") MultipartFile multipartFile) {
        String accessKeyId = "LTAI5tNsyx4gzJBqCJchymBk";
        String accessKeySecret = "u1OAewpat7JFfurYFxxTbxbNll1QZb";
        com.aliyun.ocr20191230.Client client = VehicleServiceImpl.createClient(
                accessKeyId,
                accessKeySecret);
//        InputStream inputStream = multipartFile.getInputStream();

        String file = "upload/" + multipartFile.getOriginalFilename();

        // String file = "https://viapi-test-bj.oss-cn-beijing.aliyuncs.com/viapi-3.0domepic/ocr/RecognizeBankCard/yhk1.jpg";
        FileUtils fileUtils = FileUtils.getInstance(accessKeyId, accessKeySecret);
        String ossUrl = fileUtils.upload(file);
        // 生成的url，可用于调用视觉智能开放平台的能力
        System.out.println(ossUrl);

        com.aliyun.ocr20191230.models.RecognizeLicensePlateRequest recognizeLicensePlateRequest = new com.aliyun.ocr20191230.models.RecognizeLicensePlateRequest()
                .setImageURL(ossUrl);
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        // 复制代码运行请自行打印 API 的返回值
        RecognizeLicensePlateResponse response = client.recognizeLicensePlateWithOptions(recognizeLicensePlateRequest, runtime);
        String deep = com.aliyun.teautil.Common.toJSONString(TeaModel.buildMap(response));
        System.out.println(com.aliyun.teautil.Common.toJSONString(TeaModel.buildMap(response)));


        String plateNumber = null;
        try {
            RecognizeLicensePlateResponseBody.RecognizeLicensePlateResponseBodyDataPlates plates = response.getBody().getData().getPlates().get(0);

            plateNumber = plates.getPlateNumber();
            // 继续处理...
        } catch (IndexOutOfBoundsException e) {
            // 处理异常情况
            System.out.println("Index out of bounds: " + e.getMessage());
        }


        Vehicle one = this.getOne(Wrappers.<Vehicle>lambdaQuery().eq(Vehicle::getCarNumber, plateNumber));
        if (one == null) {
            Vehicle vehicle = new Vehicle();
            vehicle.setCarNumber(plateNumber);
            vehicle.setCreateTime(new Date());
            this.save(vehicle);
            Parking parking = new Parking();
            parking.setVehicleId(vehicle.getId());
            parking.setCreateTime(new Date());
            parking.setLotId(1);
            parkingService.save(parking);
            ParkingPayment parkingPayment = new ParkingPayment();

            parkingPayment.setParkingId(parking.getId());
            parkingPayment.setCreateTime(new Date());
            parkingPaymentService.save(parkingPayment);
        } else {
            Parking parking = new Parking();
            parking.setVehicleId(one.getId());
            parking.setCreateTime(new Date());
            parking.setLotId(1);
            parkingService.save(parking);
            ParkingPayment parkingPayment = new ParkingPayment();
//            parkingPayment.setId(Math.toIntExact(snowflakeIdGenerator.generateSnowflakeId()));
            parkingPayment.setParkingId(parking.getId());
            parkingPayment.setCreateTime(new Date());
            parkingPaymentService.save(parkingPayment);
        }


        String url = fileStorageService.uploadImgFile("vehicle", multipartFile.getOriginalFilename(), multipartFile.getInputStream());
        return AjaxResult.success(url);
    }

    @Override
    @SneakyThrows
    @Transactional
    public AjaxResult outRecognition(MultipartFile file) {
        String accessKeyId = "LTAI5tNsyx4gzJBqCJchymBk";
        String accessKeySecret = "u1OAewpat7JFfurYFxxTbxbNll1QZb";
        com.aliyun.ocr20191230.Client client = VehicleServiceImpl.createClient(
                accessKeyId,
                accessKeySecret);
//        InputStream inputStream = multipartFile.getInputStream();

        String file1 = "upload/" + file.getOriginalFilename();

        // String file = "https://viapi-test-bj.oss-cn-beijing.aliyuncs.com/viapi-3.0domepic/ocr/RecognizeBankCard/yhk1.jpg";
        FileUtils fileUtils = FileUtils.getInstance(accessKeyId, accessKeySecret);
        String ossUrl = fileUtils.upload(file1);
        // 生成的url，可用于调用视觉智能开放平台的能力
        System.out.println(ossUrl);

        com.aliyun.ocr20191230.models.RecognizeLicensePlateRequest recognizeLicensePlateRequest = new com.aliyun.ocr20191230.models.RecognizeLicensePlateRequest()
                .setImageURL(ossUrl);
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        // 复制代码运行请自行打印 API 的返回值
        RecognizeLicensePlateResponse response = client.recognizeLicensePlateWithOptions(recognizeLicensePlateRequest, runtime);
        String deep = com.aliyun.teautil.Common.toJSONString(TeaModel.buildMap(response));
        System.out.println(com.aliyun.teautil.Common.toJSONString(TeaModel.buildMap(response)));


        String plateNumber = null;
        try {
            RecognizeLicensePlateResponseBody.RecognizeLicensePlateResponseBodyDataPlates plates = response.getBody().getData().getPlates().get(0);

            plateNumber = plates.getPlateNumber();
            // 继续处理...
        } catch (IndexOutOfBoundsException e) {
            // 处理异常情况
            System.out.println("Index out of bounds: " + e.getMessage());
        }

        Vehicle one = this.getOne(Wrappers.<Vehicle>lambdaQuery().eq(Vehicle::getCarNumber, plateNumber));
        if (one == null) {
            return AjaxResult.error("未找到该车牌");
        } else {
            List<Parking> parkingList = parkingService.list(Wrappers.<Parking>lambdaQuery().eq(Parking::getVehicleId, one.getId()).orderByDesc(Parking::getCreateTime));
            Parking parking = parkingList.get(0);
            if (parking == null) {
                return AjaxResult.error("未找到该车牌");
            } else {
                parking.setEndTime(new Date());
                parking.setStatus(1);
                parkingService.updateById(parking);
                List<ParkingPayment> list = parkingPaymentService.list(Wrappers.<ParkingPayment>lambdaQuery().eq(ParkingPayment::getParkingId, parking.getId()).orderByDesc(ParkingPayment::getCreateTime));
                ParkingPayment one1 = list.get(0);
                one1.setStatusId(2);
                one1.setUpdateTime(new Date());
                Instant createTime = one1.getCreateTime().toInstant();
                Instant updateTime = one1.getUpdateTime().toInstant();

                Duration between = Duration.between(createTime, updateTime);
                long hours = between.toHours();
                one1.setPayment(new BigDecimal(hours * 2));
                parkingPaymentService.updateById(one1);
                return AjaxResult.success("成功");
            }
        }


    }
    public AjaxResult updateVehicle (VehicleDto vehicleDto){
        Vehicle vehicle = new Vehicle();
        BeanUtils.copyBeanProp(vehicle, vehicleDto);
        boolean b = this.updateById(vehicle);
        if (b) {
            return AjaxResult.success();
        }
        return AjaxResult.error();
    }
    @Override
    public AjaxResult addVehicle (VehicleDto vehicleDto){
        Vehicle vehicle = new Vehicle();
        BeanUtils.copyBeanProp(vehicle, vehicleDto);
        boolean save = this.save(vehicle);
        if (save) {
            return AjaxResult.success();
        }
        return AjaxResult.error();
    }

    @Override
    public AjaxResult detVehicle (VehicleDto vehicleDto){
        boolean b = this.removeById(vehicleDto.getId());
        if (b) {
            return AjaxResult.success();
        }
        return AjaxResult.error();
    }
}




